package com.lanyou.esb.web;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeSet;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lanyou.cook.common.Constants;
import com.lanyou.cook.entity.domain.Field;
import com.lanyou.cook.entity.domain.FieldSystem;
import com.lanyou.cook.entity.domain.userManagement.User;
import com.lanyou.cook.service.security.UserSessionService;
import com.lanyou.cook.util.gson.GsonUtil;
import com.lanyou.cook.web.param.TreeNode;
import com.lanyou.esb.common.CommonUtils;
import com.lanyou.esb.datadictionary.AuditStatusType;
import com.lanyou.esb.datadictionary.EnableType;
import com.lanyou.esb.entity.Http;
import com.lanyou.esb.repository.HttpRepository;
import com.lanyou.esb.service.HttpService;
import com.lanyou.esb.service.ServiceManagerService;
import com.lanyou.esb.service.TreeHttpService;

/**
 * 领域、领域系统、HTTP接口关系展现的控制层
 * 
 * @author Davey.wu
 */
@RestController
@RequestMapping(Constants.BASE_URL_API + "/tree")
public class TreeHttpController {
	@PersistenceContext
	private EntityManager entityManager;

	@Autowired
	private UserSessionService userSessionService;

	@Autowired
	private ServiceManagerService serviceManagerService;

	@Autowired
	private HttpRepository httpRepository;

	@Autowired
	private HttpService httpService;
	
	@Autowired
	private TreeHttpService treeHttpService;

	/**
	 * 以树形结构获取领域系统接口
	 * 
	 * @return 类型:String 领域系统接口数据
	 */
	@RequestMapping(value = "/getHttp4EasyUiTree", produces = "application/json")
	public String getHttp4EasyUiTree() {
		return getLevel3Info(null, AuditStatusType.AUDITED.ValueCode, "",
				EnableType.ENABLE.ValueCode);
	}

	/**
	 * 以树形结构获取当前登录用户可管理的领域系统的接口
	 * 
	 * @return 类型:String 当前登录用户可管理的领域系统的接口数据
	 */
	@RequestMapping(value = "/getHttp4User4EasyUiTree", produces = "application/json")
	public String getHttp4User4EasyUiTree(String auditStatus,
			String operationType) {
		User user = userSessionService.getCurrentAuthenticatedUser();
		if (auditStatus == null) {
			auditStatus = "";
		}
		
		// 获取树型信息
		TreeSet<TreeNode> fieldNodes = treeHttpService.getLevel2Tree(user.getId(),
				auditStatus, operationType);
		
		return GsonUtil.getDefaultGson().toJson(fieldNodes);
	}

	/**
	 * 根据系统标识、接口审核状态及接口操作类型获取接口信息
	 * 
	 * @param systemId
	 *            ：系统编码
	 * @param auditStatus
	 *            ：接口审核状态
	 * @param operationType
	 *            ：接口操作类型
	 * @return
	 */
	@RequestMapping(value = "/getHttpBySystemId", produces = "application/json")
	public String getHttpBySystemId(String systemId, String auditStatus,
			String operationType) {
		Collator chineseCmp = Collator.getInstance(java.util.Locale.CHINA);
		Comparator<TreeNode> comparator = Comparator.comparing(
				TreeNode::getText, chineseCmp);

		// 组建树形对象，利用TreeSet进行排序
		TreeSet<TreeNode> nodes = new TreeSet<>(comparator);
		User user = userSessionService.getCurrentAuthenticatedUser();
		if (user == null) {
			return GsonUtil.getDefaultGson().toJson(nodes);
		}
		List<Http> list = httpService.getHttpInterfaceInfos(systemId,
				auditStatus, EnableType.ENABLE.ValueCode, operationType,
				user.getId());
		if (list == null || list.isEmpty()) {
			return GsonUtil.getDefaultGson().toJson(nodes);
		}
		for (Http http : list) {
			TreeNode node = CollectionUtils.find(nodes,
					n -> StringUtils.equals(http.getId(), n.getId()));
			if (node == null) {
				node = new TreeNode();
				node.setNodeType(CommonUtils.TREE_NODE_TYPE_SYSTEM_INTERFACE);
				node.setId(http.getId());
				node.setText(http.getName() + "_" + http.getVersion());
				node.setChildren(new TreeSet<>(comparator));
				node.setAuditStatus(http.getAuditStatus());
				nodes.add(node);
			}
		}
		return GsonUtil.getDefaultGson().toJson(nodes);
	}

	/**
	 * 获取三级树，第一级为领域，第二级为系统，第三级为接口
	 * 
	 * @param userCode
	 *            ：用户编码
	 * @param auditStatus
	 *            ：接口审核状态
	 * @param operateType
	 *            ：接口操作类型
	 * @param isEnable
	 *            ：接口是否可用
	 * @return
	 */
	private String getLevel3Info(String userCode, String auditStatus,
			String operationType, String isEnable) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		CriteriaQuery<Tuple> cq = cb.createTupleQuery();

		// 构建FROM和JOIN部分
		Root<Field> rootField = cq.from(Field.class);
		Join<Field, FieldSystem> joinSystem = rootField.join("fieldSystems",
				JoinType.LEFT);
		Join<FieldSystem, Http> joinHttp = joinSystem.join("httpInterfaces",
				JoinType.LEFT);
		// 接口连接条件
		List<Predicate> httpOnList = new ArrayList<>();
		if (StringUtils.isNotBlank(auditStatus)) {
			httpOnList.add(cb.equal(joinHttp.get("auditStatus"), auditStatus));
		}
		if (StringUtils.isNotBlank(operationType)) {
			httpOnList.add(cb.equal(joinHttp.get("operationType"),
					operationType));
		}
		if (StringUtils.isNotBlank(isEnable)) {
			httpOnList.add(cb.equal(joinHttp.get("isEnable"), isEnable));
		}

		if (httpOnList.size() > 0) {
			joinHttp.on(httpOnList.toArray(new Predicate[0]));
		}

		// 构建WHERE部分
		List<Predicate> predicatesList = new ArrayList<>();

		if (StringUtils.isNotEmpty(userCode)) {
			Join<FieldSystem, User> joinUser = joinSystem.join("users");
			predicatesList.add(cb.equal(joinUser.get("userCode"), userCode));
		}

		if (predicatesList.size() > 0) {
			cq.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
		}

		// 构建SELECT部分
		cq.multiselect(rootField.get("id").alias("fieldId"),
				rootField.get("name").alias("fieldName"), joinSystem.get("id")
						.alias("fieldSystemId"),
				joinSystem.get("name").alias("fieldSystemName"),
				joinHttp.get("id").alias("interfaceId"), joinHttp.get("name")
						.alias("interfaceName"),
				joinHttp.get("version").alias("version"),
				joinHttp.get("auditStatus").alias("auditStatus"));

		// 执行查询
		TypedQuery<Tuple> q = entityManager.createQuery(cq);
		List<Tuple> queryResult = q.getResultList();

		Collator chineseCmp = Collator.getInstance(java.util.Locale.CHINA);
		Comparator<TreeNode> comparator = Comparator.comparing(
				TreeNode::getText, chineseCmp);

		// 组建树形对象，利用TreeSet进行排序
		TreeSet<TreeNode> fieldNodes = new TreeSet<>(comparator);
		queryResult
				.forEach(tuple -> {
					String fieldId = tuple.get("fieldId", String.class);
					String fieldName = tuple.get("fieldName", String.class);
					String fieldSystemId = tuple.get("fieldSystemId",
							String.class);
					String fieldSystemName = tuple.get("fieldSystemName",
							String.class);
					String interfaceId = tuple.get("interfaceId", String.class);
					String interfaceName = tuple.get("interfaceName",
							String.class);
					String version = (String) tuple.get("version");
					String audit = (String) tuple.get("auditStatus");

					TreeNode fieldNode = CollectionUtils.find(fieldNodes,
							n -> StringUtils.equals(fieldId, n.getId()));
					if (fieldNode == null) {
						fieldNode = new TreeNode();
						fieldNode.setNodeType(CommonUtils.TREE_NODE_TYPE_FIELD);
						fieldNode.setId(fieldId);
						fieldNode.setText(fieldName);
						fieldNode.setChildren(new TreeSet<>(comparator));

						fieldNodes.add(fieldNode);
					}

					if (fieldSystemId == null) {
						return;
					}
					TreeNode systemNode = CollectionUtils.find(
							fieldNode.getChildren(),
							n -> StringUtils.equals(fieldSystemId, n.getId()));
					if (systemNode == null) {
						systemNode = new TreeNode();
						systemNode.setNodeType(CommonUtils.TREE_NODE_TYPE_FIELD_SYSTEM);
						systemNode.setId(fieldSystemId);
						systemNode.setText(fieldSystemName);
						systemNode.setChildren(new TreeSet<>(comparator));
						fieldNode.getChildren().add(systemNode);
					}

					if (interfaceId == null) {
						return;
					}
					TreeNode httpNode = new TreeNode();
					httpNode.setNodeType(CommonUtils.TREE_NODE_TYPE_SYSTEM_INTERFACE);
					httpNode.setId(interfaceId);
					httpNode.setText(interfaceName
							+ (StringUtils.isNotBlank(version) ? ("_" + version)
									: ""));
					httpNode.setAuditStatus(audit);
					systemNode.getChildren().add(httpNode);
				});

		return GsonUtil.getDefaultGson().toJson(fieldNodes);
	}

	/**
	 * 服务浏览展现树结构（只展现领域、系统）
	 * 
	 * @return
	 */
	@RequestMapping(value = "/findVisibleInterfaces", produces = "application/json")
	public String findVisibleInterfaces() {
		User user = userSessionService.getCurrentAuthenticatedUser();
		List<Object[]> objects = httpRepository.findVisibleInterfaces(user
				.getId());

		Collator chineseCmp = Collator.getInstance(java.util.Locale.CHINA);
		Comparator<TreeNode> comparator = Comparator.comparing(
				TreeNode::getText, chineseCmp);

		List<String> systemIds = new ArrayList<>();
		// 组建树形对象，利用TreeSet进行排序
		TreeSet<TreeNode> fieldNodes = new TreeSet<>(comparator);
		objects.forEach(object -> {
			String fieldId = (String) object[0];
			String fieldName = (String) object[1];
			String fieldSystemId = (String) object[2];
			String fieldSystemName = (String) object[3];
			String interfaceId = (String) object[4];
			String interfaceName = (String) object[5];
			String interfaceType = (String) object[6];
			String version = (String) object[7];

			TreeNode fieldNode = CollectionUtils.find(fieldNodes,
					n -> StringUtils.equals(fieldId, n.getId()));
			if (fieldNode == null) {
				fieldNode = new TreeNode();
				fieldNode.setNodeType(CommonUtils.TREE_NODE_TYPE_FIELD);
				fieldNode.setId(fieldId);
				fieldNode.setText(fieldName);
				fieldNode.setChildren(new TreeSet<>(comparator));

				fieldNodes.add(fieldNode);
			}

			if (fieldSystemId == null)
				return;
			TreeNode fieldSystemNode = CollectionUtils.find(
					fieldNode.getChildren(),
					n -> StringUtils.equals(fieldSystemId, n.getId()));
			if (fieldSystemNode == null) {
				systemIds.add(fieldSystemId);
				fieldSystemNode = new TreeNode();
				fieldSystemNode.setNodeType(CommonUtils.TREE_NODE_TYPE_FIELD_SYSTEM);
				fieldSystemNode.setId(fieldSystemId);
				fieldSystemNode.setText(fieldSystemName);
				fieldSystemNode.setChildren(new TreeSet<>(comparator));
				fieldSystemNode.setIfIds(interfaceId);
				fieldNode.getChildren().add(fieldSystemNode);
			}else{
				String ifIds = fieldSystemNode.getIfIds();
				fieldSystemNode.setIfIds(ifIds += (StringUtils.isNotBlank(ifIds) == true?",":"") + interfaceId);
			}

			/*
			 * if (interfaceId == null) return; TreeNode systemInterfaceNode =
			 * new TreeNode();
			 * systemInterfaceNode.setNodeType("systemInterface");
			 * systemInterfaceNode.setId(interfaceId);
			 * systemInterfaceNode.setText(interfaceName +
			 * (StringUtils.isNotBlank(version) ? ("_" + version) : ""));
			 * systemInterfaceNode.setInterfaceType(interfaceType);
			 * fieldSystemNode.getChildren().add(systemInterfaceNode);
			 */
		});

		// 获取存在接口的系统集合
		Map<String, Boolean> map = serviceManagerService.getSystemExistsHttp(
				systemIds, EnableType.ENABLE.ValueCode);
		for (TreeNode treeNode : fieldNodes) {
			if (treeNode.getChildren() != null) {
				// 遍历系统节点
				for (TreeNode children : treeNode.getChildren()) {
					// 存在接口
					if (map.get(children.getId()) != null) {
						children.setHasChildren(true);
						continue;
					}
					// 不存在接口
					children.setHasChildren(false);
				}
			}
		}
		return GsonUtil.getDefaultGson().toJson(fieldNodes);
	}

	/**
	 * 报文管理展现树结构（只展现领域、系统）
	 * 
	 * @return
	 */
	@RequestMapping(value = "/findInterfacesForMsgByUser", produces = "application/json")
	public String findInterfacesForMsgByUser() {
		User user = userSessionService.getCurrentAuthenticatedUser();
		List<Object[]> objects = httpRepository.findInterfacesForMsgByUser(user
				.getId());

		Collator chineseCmp = Collator.getInstance(java.util.Locale.CHINA);
		Comparator<TreeNode> comparator = Comparator.comparing(
				TreeNode::getText, chineseCmp);
		List<String> systemIds = new ArrayList<>();
		// 组建树形对象，利用TreeSet进行排序
		TreeSet<TreeNode> fieldNodes = new TreeSet<>(comparator);
		objects.forEach(object -> {
			String fieldId = (String) object[0];
			String fieldName = (String) object[1];
			String fieldSystemId = (String) object[2];
			String fieldSystemName = (String) object[3];
			String interfaceId = (String) object[4];
			String interfaceName = (String) object[5];
			String interfaceType = (String) object[6];
			String version = (String) object[7];

			TreeNode fieldNode = CollectionUtils.find(fieldNodes,
					n -> StringUtils.equals(fieldId, n.getId()));
			if (fieldNode == null) {
				fieldNode = new TreeNode();
				fieldNode.setNodeType(CommonUtils.TREE_NODE_TYPE_FIELD);
				fieldNode.setId(fieldId);
				fieldNode.setText(fieldName);
				fieldNode.setChildren(new TreeSet<>(comparator));

				fieldNodes.add(fieldNode);
			}

			if (fieldSystemId == null)
				return;
			TreeNode fieldSystemNode = CollectionUtils.find(
					fieldNode.getChildren(),
					n -> StringUtils.equals(fieldSystemId, n.getId()));
			if (fieldSystemNode == null) {
				systemIds.add(fieldSystemId);
				fieldSystemNode = new TreeNode();
				fieldSystemNode.setNodeType(CommonUtils.TREE_NODE_TYPE_FIELD_SYSTEM);
				fieldSystemNode.setId(fieldSystemId);
				fieldSystemNode.setText(fieldSystemName);
				fieldSystemNode.setChildren(new TreeSet<>(comparator));
				fieldNode.getChildren().add(fieldSystemNode);
			}

			/*
			 * if (interfaceId == null) return; TreeNode systemInterfaceNode =
			 * new TreeNode();
			 * systemInterfaceNode.setNodeType("systemInterface");
			 * systemInterfaceNode.setId(interfaceId);
			 * systemInterfaceNode.setText(interfaceName +
			 * (StringUtils.isNotBlank(version) ? ("_" + version) : ""));
			 * systemInterfaceNode.setInterfaceType(interfaceType);
			 * fieldSystemNode.getChildren().add(systemInterfaceNode);
			 */
		});

		// 获取存在接口的系统集合
		Map<String, Boolean> map = serviceManagerService.getSystemExistsHttp(
				systemIds, EnableType.ENABLE.ValueCode);
		for (TreeNode treeNode : fieldNodes) {
			if (treeNode.getChildren() != null) {
				// 遍历系统节点
				for (TreeNode children : treeNode.getChildren()) {
					// 存在接口
					if (map.get(children.getId()) != null) {
						children.setHasChildren(true);
						continue;
					}
					// 不存在接口
					children.setHasChildren(false);
				}
			}
		}
		return GsonUtil.getDefaultGson().toJson(fieldNodes);
	}

	/**
	 * 服务浏览中根据系统标识、获取接口信息
	 * 
	 * @param systemId
	 *            ：系统编码
	 * @return
	 */
	@RequestMapping(value = "/getHttpBySystemIdForScan", produces = "application/json")
	public String getHttpBySystemIdForScan(String systemId, String ifIds) {
		Collator chineseCmp = Collator.getInstance(java.util.Locale.CHINA);
		Comparator<TreeNode> comparator = Comparator.comparing(
				TreeNode::getText, chineseCmp);

		// 组建树形对象，利用TreeSet进行排序
		TreeSet<TreeNode> nodes = new TreeSet<>(comparator);
		List<String> idsList = new ArrayList<>();
		if(ifIds.contains(",")){
			String[] Ids = ifIds.split(",");
			for (String id : Ids) {
				idsList.add(id);
			}
		}else{
			idsList.add(ifIds);
		}
		List<Http> list = serviceManagerService.getHttpInterfaceInfos(systemId,
				idsList, EnableType.ENABLE.ValueCode);
		if (list == null || list.isEmpty()) {
			return GsonUtil.getDefaultGson().toJson(nodes);
		}
		for (Http http : list) {
			TreeNode node = CollectionUtils.find(nodes,
					n -> StringUtils.equals(http.getId(), n.getId()));
			if (node == null) {
				node = new TreeNode();
				node.setNodeType(CommonUtils.TREE_NODE_TYPE_SYSTEM_INTERFACE);
				node.setId(http.getId());
				node.setText(http.getName() + "_" + http.getVersion());
				node.setInterfaceType(http.getType());
				node.setChildren(new TreeSet<>(comparator));

				nodes.add(node);
			}
		}
		return GsonUtil.getDefaultGson().toJson(nodes);
	}

	/**
	 * 报文管理中根据系统标识、获取接口信息
	 * 
	 * @param systemId
	 *            ：系统编码
	 * @return
	 */
	@RequestMapping(value = "/getHttpBySystemIdForMsgScan", produces = "application/json")
	public String getHttpBySystemIdForMsgScan(String systemId) {
		Collator chineseCmp = Collator.getInstance(java.util.Locale.CHINA);
		Comparator<TreeNode> comparator = Comparator.comparing(
				TreeNode::getText, chineseCmp);

		// 组建树形对象，利用TreeSet进行排序
		TreeSet<TreeNode> nodes = new TreeSet<>(comparator);

		List<Http> list = serviceManagerService.getHttpInterfaceInfosForMsg(
				systemId, EnableType.ENABLE.ValueCode);
		if (list == null || list.isEmpty()) {
			return GsonUtil.getDefaultGson().toJson(nodes);
		}
		for (Http http : list) {
			TreeNode node = CollectionUtils.find(nodes,
					n -> StringUtils.equals(http.getId(), n.getId()));
			if (node == null) {
				node = new TreeNode();
				node.setNodeType(CommonUtils.TREE_NODE_TYPE_SYSTEM_INTERFACE);
				node.setId(http.getId());
				node.setText(http.getName() + "_" + http.getVersion());
				node.setInterfaceType(http.getType());
				node.setChildren(new TreeSet<>(comparator));

				nodes.add(node);
			}
		}
		return GsonUtil.getDefaultGson().toJson(nodes);
	}
}
